package com.ibeeking.found.cop.b.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ibeeking.found.common.config.prop.FileOssProp;
import com.ibeeking.found.common.enums.PublishStatusEnum;
import com.ibeeking.found.common.enums.SyncStatusEnum;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.cop.b.rest.service.ICopAttachementService;
import com.ibeeking.found.cop.b.rest.service.IGroupWelcomeService;
import com.ibeeking.found.cop.b.rest.service.IMqService;
import com.ibeeking.found.cop.b.rest.service.IWxOpenService;
import com.ibeeking.found.cop.service.common.dos.GroupWelcomeDO;
import com.ibeeking.found.cop.service.common.enums.MqSyncOperatorTypeEnum;
import com.ibeeking.found.cop.service.common.param.CopAttachementParam;
import com.ibeeking.found.cop.service.common.param.GroupWelcomeParam;
import com.ibeeking.found.cop.service.common.param.MqSyncCopParam;
import com.ibeeking.found.cop.service.common.param.UniAttachParam;
import com.ibeeking.found.cop.service.common.query.CopAttachementQuery;
import com.ibeeking.found.cop.service.common.query.GroupWelcomeQuery;
import com.ibeeking.found.cop.service.common.vo.CopAttachementVO;
import com.ibeeking.found.cop.service.common.vo.GroupWelcomeVO;
import com.ibeeking.found.cop.service.common.vo.UniAttachVO;
import com.ibeeking.found.cop.service.mapper.GroupWelcomeMapper;
import com.ibeeking.found.id.GenerateId;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.json.JsonUtils;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpExternalContactService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpBaseResp;
import me.chanjar.weixin.cp.bean.external.WxCpGroupWelcomeTemplateResult;
import me.chanjar.weixin.cp.bean.external.msg.Attachment;
import me.chanjar.weixin.cp.bean.external.msg.Text;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName GroupWelcomeServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-01-27 18:50
 **/
@Service
public class GroupWelcomeServiceImpl  extends ServiceImpl<GroupWelcomeMapper, GroupWelcomeDO> implements IGroupWelcomeService {

    @Resource
    private GroupWelcomeMapper groupWelcomeMapper;

    @Resource
    private ICopAttachementService copAttachementServiceImpl;

    @Resource
    private IWxOpenService wxOpenServiceImpl;

    @Resource
    private IMqService mqServiceImpl;

    @Resource
    private FileOssProp fileOssProp;

    @Override
    public List<GroupWelcomeVO> list(GroupWelcomeQuery query) {
        List<GroupWelcomeDO> entityDOS = groupWelcomeMapper.selectList(new LambdaQueryWrapper<GroupWelcomeDO>()
                .eq(query.getId() != null, GroupWelcomeDO::getId, query.getId())
                .like(StringUtils.isNotBlank(query.getContent()), GroupWelcomeDO::getContent, query.getContent())
                .eq(query.getStatus() != null, GroupWelcomeDO::getStatus, query.getStatus())
                .orderByDesc(GroupWelcomeDO::getCreateTime)
        );
        List<GroupWelcomeVO> entityVOS =JsonUtils.jsonToList(entityDOS, GroupWelcomeVO.class);
        if(Collections3.isNotEmpty(entityVOS)) {
            List<Long> ids = entityVOS.stream().map(GroupWelcomeVO::getId).collect(Collectors.toList());
            CopAttachementQuery attachementQuery = new CopAttachementQuery();
            attachementQuery.setMessageIds(ids);
            List<CopAttachementVO> copAttachementVOS = copAttachementServiceImpl.list(attachementQuery);
            Map<Long, CopAttachementVO> copAttachementMap = Collections3.isNotEmpty(copAttachementVOS)?copAttachementVOS.stream().collect(Collectors.toMap(CopAttachementVO::getMessageId, x->x, (o, n) -> n)):null;
            entityVOS.forEach(x -> {
                x.setStatusDesc(PublishStatusEnum.getName(x.getStatus()));
                x.setSyncStatusDesc(SyncStatusEnum.getName(x.getSyncStatus()));
                CopAttachementVO copAttachementVO = copAttachementMap!=null && copAttachementMap.size()>0?copAttachementMap.get(x.getId()):null;
                if(copAttachementVO!=null){
                    List<UniAttachVO> uniAttachVOS = copAttachementServiceImpl.transerCopAttachementToUniAttachement(copAttachementVO);
                    x.setAttachements(uniAttachVOS);
                }
            });
        }
        return entityVOS;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(GroupWelcomeParam param) {
        GroupWelcomeDO entityDO = BeanUtil.convertBean(param, GroupWelcomeDO.class);
        Long id = GenerateId.generateId();
        entityDO.setId(id);
        entityDO.setSyncStatus(SyncStatusEnum.SYNC_NO.getValue());
        entityDO.setStatus(PublishStatusEnum.DISABLE.getValue());
        List<UniAttachParam> uniAttachParams = param.getAttachements();
        if(Collections3.isNotEmpty(uniAttachParams)){
            CopAttachementParam copAttachementParam = copAttachementServiceImpl.transerUniAttachementToCopAttachement(uniAttachParams);
            if(copAttachementParam!=null){
                copAttachementParam.setMessageId(id);
                copAttachementServiceImpl.add(copAttachementParam);
            }
        }
        entityDO.setCreateBy(UserUtils.getUserId());
        entityDO.setCreateTime(LocalDateTime.now());
        entityDO.setModifyTime(LocalDateTime.now());
        return groupWelcomeMapper.insert(entityDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean modify(GroupWelcomeParam param) {
        GroupWelcomeDO entityDO = BeanUtil.convertBean(param, GroupWelcomeDO.class);
        entityDO.setSyncStatus(SyncStatusEnum.SYNC_NO.getValue());
        List<UniAttachParam> uniAttachParams = param.getAttachements();
        if(Collections3.isNotEmpty(uniAttachParams)){
            CopAttachementParam copAttachementParam = copAttachementServiceImpl.transerUniAttachementToCopAttachement(uniAttachParams);
            if(copAttachementParam!=null){
                copAttachementParam.setMessageId(entityDO.getId());
                copAttachementServiceImpl.modify(copAttachementParam);
            }
        }
        entityDO.setModifyBy(UserUtils.getUserId());
        entityDO.setModifyTime(LocalDateTime.now());
        return groupWelcomeMapper.updateById(entityDO) > 0;
    }

    @Override
    public GroupWelcomeVO view(Long id) {
        GroupWelcomeDO entityDO = groupWelcomeMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        GroupWelcomeVO entityVO = BeanUtil.convertBean(entityDO, GroupWelcomeVO.class);
        if(entityVO != null) {
            entityVO.setStatusDesc(PublishStatusEnum.getName(entityDO.getStatus()));
            entityVO.setSyncStatusDesc(SyncStatusEnum.getName(entityDO.getSyncStatus()));
            CopAttachementVO copAttachementVO = copAttachementServiceImpl.queryByMessageId(id);
            if(null != copAttachementVO) {
                List<UniAttachVO> uniAttachVOS = copAttachementServiceImpl.transerCopAttachementToUniAttachement(copAttachementVO);
                entityVO.setAttachements(uniAttachVOS);
            }
        }
        return entityVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean changeStatus(Long id, Integer status) {
        GroupWelcomeDO entityDO = groupWelcomeMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        entityDO.setStatus(status);
        entityDO.setModifyBy(UserUtils.getUserId());
        entityDO.setModifyTime(LocalDateTime.now());
        return groupWelcomeMapper.updateById(entityDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean del(Long id) {
        GroupWelcomeDO entityDO = groupWelcomeMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        if(entityDO.getSyncStatus() == SyncStatusEnum.SYNC_YES.getValue()) {
            Integer result = this.getBean().sendInstructionToMq(id, MqSyncOperatorTypeEnum.COP_SYNC_GROUPS_WELCOME_DEL.getCode());
            if (result <= 0) throw new BusinessException("同步删除企微的欢迎语失败，请联系管理员！");
        }
        copAttachementServiceImpl.delByMessageId(id);
        return groupWelcomeMapper.deleteById(id) > 0;
    }
    /***
     *
     * 向Mq发送执行指令
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer sendInstructionToMq(Long id, String operType){
        String tenantId = UserUtils.getTenantId();
        MqSyncCopParam mqParam = new MqSyncCopParam();
        mqParam.setTenantId(Long.valueOf(tenantId));
        mqParam.setId(id);
        mqParam.setOperType(operType);
        mqServiceImpl.sendSyncToWxTaskMessage(mqParam);
        return 1;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Integer syncGroupWelcomeToWxCp(Integer tenantId,Long id, Boolean deleted){
        GroupWelcomeDO entityDO = groupWelcomeMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        CopAttachementVO oldCopAttachementVO = copAttachementServiceImpl.queryByMessageId(id);
        String templateId = entityDO.getTemplateId();

        WxCpService wxCpService = wxOpenServiceImpl.getWxCpService(tenantId.longValue());
        WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
        if (wxCpConfigStorage == null) {
            throw new BusinessException("获取企微服务失败!");
        }
        String corpId = wxCpConfigStorage.getCorpId();
        Integer agentId = wxCpConfigStorage.getAgentId();

        WxCpExternalContactService wxCpExternalContactService = wxCpService.getExternalContactService();
        if (wxCpExternalContactService == null) throw new BusinessException("获取企微服务外部联系人服务!");
        if(deleted){
            try {
                if(agentId == null) return 0;
                if (StringUtils.isEmpty(templateId)) return 0;
                WxCpBaseResp wxCpBaseResp = wxCpExternalContactService.delGroupWelcomeTemplate(templateId, null);
                if (!wxCpBaseResp.success()) {
                    return 0;
                }
            } catch (WxErrorException ex) {
                return 0;
            }
        }else {
            WxCpGroupWelcomeTemplateResult wxCpGroupWelcomeTemplateResult = new WxCpGroupWelcomeTemplateResult();
            if(StringUtils.isNotEmpty(entityDO.getContent())) {
                me.chanjar.weixin.cp.bean.external.msg.Text contentText = new Text();
                contentText.setContent(entityDO.getContent());
                wxCpGroupWelcomeTemplateResult.setText(contentText);
            }
            if(oldCopAttachementVO!=null){
                if(copAttachementServiceImpl.syncMessageAttachementsToWxCp(id)) {
                    CopAttachementVO newCopAttachementVO = copAttachementServiceImpl.queryByMessageId(id);
                    LogUtils.info("+++++++++newCopAttachementVO:{}+++++++++", JsonUtils.toJsonStr(newCopAttachementVO));
                    if(newCopAttachementVO!=null) {
                        List<CopAttachementVO> newCopAttachementVOS = new ArrayList<>();
                        newCopAttachementVOS.add(newCopAttachementVO);
                        List<Attachment> wxcpAttachements = copAttachementServiceImpl.transerCopAttachementToWxcpAttachement(newCopAttachementVOS);
                        if (Collections3.isNotEmpty(wxcpAttachements)) {
                            Attachment wxcpAttachment = wxcpAttachements.get(0);
                            if(wxcpAttachment!=null) {
                                if(wxcpAttachment.getImage()!=null) {
                                    wxCpGroupWelcomeTemplateResult.setImage(wxcpAttachment.getImage());
                                }
                                if(wxcpAttachment.getVideo()!=null) {
                                    wxCpGroupWelcomeTemplateResult.setVideo(wxcpAttachment.getVideo());
                                }
                                if(wxcpAttachment.getFile()!=null) {
                                    wxCpGroupWelcomeTemplateResult.setFile(wxcpAttachment.getFile());
                                }
                                if(wxcpAttachment.getLink()!=null) {
                                    wxCpGroupWelcomeTemplateResult.setLink(wxcpAttachment.getLink());
                                }
                                if(wxcpAttachment.getMiniProgram()!=null) {
                                    wxCpGroupWelcomeTemplateResult.setMiniprogram(wxcpAttachment.getMiniProgram());
                                }
                            }
                        }
                    }
                }
            }
            wxCpGroupWelcomeTemplateResult.setNotify(1);
            if (StringUtils.isEmpty(templateId)) {
                try {
                    LogUtils.info("+++++++++add wxCpGroupWelcomeTemplateResult:{}+++++++++", JsonUtils.toJsonStr(wxCpGroupWelcomeTemplateResult));
                    String returnTemplateId = wxCpExternalContactService.addGroupWelcomeTemplate(wxCpGroupWelcomeTemplateResult);
                    if (StringUtils.isNotEmpty(returnTemplateId)) {
                        entityDO.setTemplateId(returnTemplateId);
                        entityDO.setSyncStatus(SyncStatusEnum.SYNC_YES.getValue());
                    } else {
                        entityDO.setTemplateId(null);
                        entityDO.setSyncStatus(SyncStatusEnum.SYNC_NO.getValue());
                    }
                } catch (WxErrorException ex) {
                    LogUtils.error("同步入群欢迎语出错" + ex);
                    entityDO.setTemplateId(null);
                    entityDO.setSyncStatus(SyncStatusEnum.SYNC_NO.getValue());
                }
            } else {
                try {
                    wxCpGroupWelcomeTemplateResult.setTemplateId(templateId);
                    LogUtils.info("+++++++++update wxCpGroupWelcomeTemplateResult:{}+++++++++", JsonUtils.toJsonStr(wxCpGroupWelcomeTemplateResult));
                    WxCpBaseResp wxCpBaseResp = wxCpExternalContactService.editGroupWelcomeTemplate(wxCpGroupWelcomeTemplateResult);
                    if (wxCpBaseResp.success()) {
                        entityDO.setSyncStatus(SyncStatusEnum.SYNC_YES.getValue());
                    } else {
                        entityDO.setSyncStatus(SyncStatusEnum.SYNC_NO.getValue());
                    }
                } catch (WxErrorException ex) {
                    LogUtils.error("同步入群欢迎语出错" + ex);
                    entityDO.setSyncStatus(SyncStatusEnum.SYNC_NO.getValue());
                }
            }
            if (entityDO != null) {
                groupWelcomeMapper.updateById(entityDO);
            }
        }
        return 1;
    }
    /**
     * 校验唯一性
     *
     * @param param
     */
    public void checkUnique(GroupWelcomeParam param) {
        if (param == null) {
            throw new BusinessException("当前记录不存在!");
        }
        //code name确保等级唯一性
        LambdaQueryWrapper<GroupWelcomeDO> queryWrapper = new LambdaQueryWrapper<GroupWelcomeDO>()
                .ne(param.getId() != null, GroupWelcomeDO::getId, param.getId())
                .eq(GroupWelcomeDO::getContent, param.getContent());
        List<GroupWelcomeDO> dos = groupWelcomeMapper.selectList(queryWrapper);
        if (Collections3.isNotEmpty(dos)) {
            throw new BusinessException("已经存在同名的记录!");
        }
    }

    private IGroupWelcomeService getBean(){
        return SpringBeanUtil.getBean(GroupWelcomeServiceImpl.class);
    }
}
